home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 December / december_2000.iso / Intercd / root / Multimedia / audio / ^NoiseTracker / NtkSourceCode / Alphatrack.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-07  |  21.9 KB  |  1,035 lines

  1.  
  2. // CSynth V1.4 Class for C++
  3. // Description: Analogue Physical Modelling Simulation of monophonic
  4. // Vintage modular synthesizer in realtime. 32 Bit float resolution.
  5. // 
  6. // By Juan Antonio Arguelles Rius <gx11488@agger.net>
  7. //
  8. // Feel free to comment/send any suggestions, optimizations or 
  9. // depuration of this code. 
  10. //
  11. // Or implement your new members/routines.
  12. //
  13. // Current Components:
  14. //
  15. // * 2 Oscillators [5 Modes: Sine, Sawtooth, 
  16. //   Pulse[with Pulse Width control], Noise and Oscillator Off]
  17. //   including Volume Control for each OSC.
  18. // * Sub Oscillator
  19. // * 1 VCF (Voltage Controlled Filter)
  20. //   [3 Types: Lowpass, Highpass, Thru] with Resonance control.
  21. // * 2 ADSR Envelope Generators.
  22. // * 2 Low Frequency Oscillators.
  23. // * Modulation Matrix parameters
  24.  
  25. float SIN[360]; // Sine float-precalculated table, in absolute degrees.
  26.  
  27. /* Struct used to store/update synthesizer parameters */
  28.  
  29. struct SynthParameters
  30. {
  31.  
  32. char presetname[20];
  33.  
  34. unsigned char osc1_waveform; /* 0 - 4 */
  35. unsigned char osc2_waveform;
  36.     
  37. int osc1_pw; /* 0 - 512 */
  38. int osc2_pw;    
  39.  
  40. unsigned char osc2_detune; /* 0 - 128 */
  41. unsigned char osc2_finetune; /* 0 - 128 */
  42.     
  43. unsigned char vcf_cutoff; /* 0 - 128 */
  44. unsigned char vcf_resonance; /* 0 - 128 */
  45.  
  46. unsigned char vcf_type; /* 0 - 2 */ 
  47.  
  48. /* Envelopes and LFO's properties */
  49.  
  50. int env1_attack; /* In samples */
  51. int env1_decay;
  52. unsigned char env1_sustain; /* 0 -128 */
  53. int env1_release;
  54.  
  55. int env2_attack; /* In samples */
  56. int env2_decay;
  57. unsigned char env2_sustain; /* 0 -128 */
  58. int env2_release;
  59.  
  60. int lfo1_period;
  61. int lfo2_period;
  62.  
  63. /* Envelopes and LFO's modulation variables */
  64.  
  65. unsigned char lfo1_osc1_pw;
  66. unsigned char lfo1_osc2_pw;
  67. unsigned char lfo1_osc1_pitch;
  68. unsigned char lfo1_osc2_pitch;
  69. unsigned char lfo1_osc1_volume;
  70. unsigned char lfo1_osc2_volume;    
  71. unsigned char lfo1_vcf_cutoff;
  72. unsigned char lfo1_vcf_resonance;    
  73.  
  74. unsigned char lfo2_osc1_pw;
  75. unsigned char lfo2_osc2_pw;
  76. unsigned char lfo2_osc1_pitch;
  77. unsigned char lfo2_osc2_pitch;
  78. unsigned char lfo2_osc1_volume;
  79. unsigned char lfo2_osc2_volume;    
  80. unsigned char lfo2_vcf_cutoff;
  81. unsigned char lfo2_vcf_resonance;    
  82.  
  83. unsigned char env1_osc1_pw;
  84. unsigned char env1_osc2_pw;
  85. unsigned char env1_osc1_pitch;
  86. unsigned char env1_osc2_pitch;
  87. unsigned char env1_osc1_volume;
  88. unsigned char env1_osc2_volume;    
  89. unsigned char env1_vcf_cutoff;
  90. unsigned char env1_vcf_resonance;    
  91.  
  92. unsigned char env2_osc1_pw;
  93. unsigned char env2_osc2_pw;
  94. unsigned char env2_osc1_pitch;
  95. unsigned char env2_osc2_pitch;
  96. unsigned char env2_osc1_volume;
  97. unsigned char env2_osc2_volume;    
  98. unsigned char env2_vcf_cutoff;
  99. unsigned char env2_vcf_resonance;
  100.  
  101. unsigned char osc3_volume;
  102. bool osc3_switch;
  103.  
  104. unsigned char ptc_glide;
  105. unsigned char glb_volume;
  106.  
  107. /* hehe, 46 parameters =] */
  108. };
  109.  
  110. class CSynth{
  111. public:
  112.  
  113. /* Synthesizer Prototype Functions */
  114.  
  115.     /* Initialization or parameter update */
  116.  
  117.     
  118.     char ENV1_STAGE;
  119.     char ENV2_STAGE;
  120.  
  121.     void SynthReset(void);
  122.     void SynthChangeParameters(SynthParameters TSP);
  123.  
  124.     /* Work functions */
  125.  
  126.     float SynthGetSample(void);
  127.     void SynthNoteOn(float note, float speed);
  128.     void SynthNoteOff(void);
  129.     
  130. private:
  131.  
  132.     /* Internal Use */
  133.  
  134.     void SynthEnvUpdate(void);
  135.     void SynthLfoAdvance(void);
  136.     void SynthEnvRun(void);
  137.     float SynthGetOscValue(char type,float offset);
  138.     float SynthFilter(float input);
  139.     
  140. /* Synthesizer properties */
  141.  
  142.     char OSC1_WAVEFORM;
  143.     char OSC2_WAVEFORM;
  144.     
  145.     float OSC1_PW;
  146.     float OSC2_PW;    
  147.  
  148.     float T_OSC1_PW;
  149.     float T_OSC2_PW;
  150.     float T_OSC1_VOLUME;
  151.     float T_OSC2_VOLUME;
  152.  
  153.     float GLOBAL_VOLUME;
  154.  
  155.     float T_OSC1_STEP;
  156.     float T_OSC2_STEP;
  157.     float VT_OSC1_STEP;
  158.     float VT_OSC2_STEP;
  159.     
  160.     float OSC2_DETUNE;
  161.     float OSC2_FINETUNE;    
  162.     
  163.     float VCF_CUTOFF;
  164.     float VCF_RESONANCE;
  165.     char VCF_TYPE;
  166.  
  167. /* Envelopes and LFO's properties */
  168.  
  169.     int ENV1_ATTACK;
  170.     int ENV1_DECAY;
  171.     float ENV1_SUSTAIN;
  172.     int ENV1_RELEASE;
  173.  
  174.     float ENV1_A_COEF;
  175.     float ENV1_D_COEF;
  176.     float ENV1_R_COEF;
  177.  
  178.     int ENV2_ATTACK;
  179.     int ENV2_DECAY;
  180.     float ENV2_SUSTAIN;
  181.     int ENV2_RELEASE;
  182.     
  183.     float ENV2_A_COEF;
  184.     float ENV2_D_COEF;
  185.     float ENV2_R_COEF;
  186.  
  187.     float LFO1_PERIOD;
  188.     float LFO2_PERIOD;
  189.  
  190.     int LFO1_GR;
  191.     int LFO2_GR;
  192.     
  193.     int LFO1_SUBGRCOUNTER;
  194.     int LFO2_SUBGRCOUNTER;
  195.     
  196.     int LFO1_SUBGRMAX;
  197.     int LFO2_SUBGRMAX;
  198.     
  199.     float LFO1_VALUE;
  200.     float LFO2_VALUE;
  201.  
  202. /* Envelopes and LFO's modulation variables */
  203.  
  204.     float LFO1_OSC1_PW;
  205.     float LFO1_OSC2_PW;
  206.     float LFO1_OSC1_PITCH;
  207.     float LFO1_OSC2_PITCH;
  208.     float LFO1_OSC1_VOLUME;
  209.     float LFO1_OSC2_VOLUME;    
  210.     float LFO1_VCF_CUTOFF;
  211.     float LFO1_VCF_RESONANCE;    
  212.  
  213.     float LFO2_OSC1_PW;
  214.     float LFO2_OSC2_PW;
  215.     float LFO2_OSC1_PITCH;
  216.     float LFO2_OSC2_PITCH;
  217.     float LFO2_OSC1_VOLUME;
  218.     float LFO2_OSC2_VOLUME;    
  219.     float LFO2_VCF_CUTOFF;
  220.     float LFO2_VCF_RESONANCE;    
  221.  
  222.     float ENV1_OSC1_PW;
  223.     float ENV1_OSC2_PW;
  224.     float ENV1_OSC1_PITCH;
  225.     float ENV1_OSC2_PITCH;
  226.     float ENV1_OSC1_VOLUME;
  227.     float ENV1_OSC2_VOLUME;    
  228.     float ENV1_VCF_CUTOFF;
  229.     float ENV1_VCF_RESONANCE;    
  230.  
  231.     float ENV2_OSC1_PW;
  232.     float ENV2_OSC2_PW;
  233.     float ENV2_OSC1_PITCH;
  234.     float ENV2_OSC2_PITCH;
  235.     float ENV2_OSC1_VOLUME;
  236.     float ENV2_OSC2_VOLUME;    
  237.     float ENV2_VCF_CUTOFF;
  238.     float ENV2_VCF_RESONANCE;    
  239.  
  240. /* Internal rendering variables */
  241.  
  242.     float OSC1_POSITION;
  243.     float OSC2_POSITION;
  244.     float OSC3_POSITION;
  245.  
  246.     float TOSC1_POSITION;
  247.     float TOSC2_POSITION;
  248.     
  249.     float OSC1_STEP;
  250.     float OSC2_STEP;
  251.     float OSC3_STEP;
  252.  
  253.     int ENV1_COUNTER;
  254.     int ENV2_COUNTER;
  255.  
  256.     float ENV1_VALUE;
  257.     float ENV2_VALUE;
  258.  
  259.     float OSC3_VOLUME;
  260.     bool OSC3_SWITCH;
  261.  
  262.     float OSC1_freakpw1;
  263.     float OSC1_freakpw2;
  264.  
  265.     float OSC2_freakpw1;
  266.     float OSC2_freakpw2;
  267.  
  268.     float sbuf0;
  269.     float sbuf1;
  270.  
  271.     float GS_VAL;
  272.     float PTC_GLIDE;
  273.  
  274.     float GLB_VOLUME;
  275. };
  276.  
  277.  
  278. /* This next function resets the synthesizer to default values */
  279.  
  280. void CSynth::SynthReset(void)
  281. {
  282.     /* Synthesizer General Reset */
  283.  
  284.     GS_VAL=0;
  285.     GLB_VOLUME=1.0f;
  286.     OSC1_WAVEFORM=1; /* Sawtooth */
  287.     OSC2_WAVEFORM=1; /* Sawtooth */
  288.     
  289.     OSC1_PW=0; /* Square (Middle Width) */
  290.     OSC2_PW=0; /* Square */    
  291.  
  292.     T_OSC1_PW=0;
  293.     T_OSC2_PW=0;
  294.  
  295.     T_OSC1_VOLUME=0;
  296.     T_OSC2_VOLUME=0;
  297.  
  298.     GLOBAL_VOLUME=0;
  299.  
  300.     OSC2_DETUNE=0; /* No Semitone Detune */
  301.     OSC2_FINETUNE=0.1f;    /* 1/10 Semitone detune */
  302.     
  303.     VCF_CUTOFF=0.5f; /* 10000Hz Cutoff */
  304.     VCF_RESONANCE=0.5f; /* Not very weird =] */
  305.     VCF_TYPE=0; /* LowPass filter */
  306.  
  307.     ENV1_ATTACK=2560; /* About 59 miliseconds */
  308.     ENV1_DECAY=2560; /* The same here */
  309.     ENV1_SUSTAIN=0.3f; /* Sustain volume at 1/3 */
  310.     ENV1_RELEASE=16384; /* About 371 Miliseconds */ 
  311.  
  312.     ENV2_ATTACK=2560; /* About 59 miliseconds */
  313.     ENV2_DECAY=2560; /* The same here */
  314.     ENV2_SUSTAIN=0.3f; /* Sustain volume at 1/3 */
  315.     ENV2_RELEASE=16384; /* About 371 Miliseconds */ 
  316.  
  317.     SynthEnvUpdate(); /* Update And Compute ENV1 and ENV2 coefficients */
  318.  
  319.     LFO1_PERIOD=16;
  320.     LFO2_PERIOD=16;
  321.  
  322.     LFO1_GR=0;
  323.     LFO2_GR=0;
  324.  
  325.     LFO1_SUBGRCOUNTER=0;
  326.     LFO2_SUBGRCOUNTER=0;
  327.  
  328.     LFO1_SUBGRMAX=200;
  329.     LFO2_SUBGRMAX=200;
  330.  
  331.     LFO1_VALUE=0;
  332.     LFO2_VALUE=0;
  333.  
  334.     LFO1_OSC1_PW=0;
  335.     LFO1_OSC2_PW=0;
  336.     LFO1_OSC1_PITCH=0;
  337.     LFO1_OSC2_PITCH=0;
  338.     LFO1_OSC1_VOLUME=0;
  339.     LFO1_OSC2_VOLUME=0;    
  340.     LFO1_VCF_CUTOFF=0;
  341.     LFO1_VCF_RESONANCE=0;    
  342.     
  343.     LFO2_OSC1_PW=0;
  344.     LFO2_OSC2_PW=0;
  345.     LFO2_OSC1_PITCH=0;
  346.     LFO2_OSC2_PITCH=0;
  347.     LFO2_OSC1_VOLUME=0;
  348.     LFO2_OSC2_VOLUME=0;    
  349.     LFO2_VCF_CUTOFF=0;
  350.     LFO2_VCF_RESONANCE=0;    
  351.  
  352.     ENV1_OSC1_PW=0;
  353.     ENV1_OSC2_PW=0;
  354.     ENV1_OSC1_PITCH=0;
  355.     ENV1_OSC2_PITCH=0;
  356.     ENV1_OSC1_VOLUME=1.0;
  357.     ENV1_OSC2_VOLUME=1.0;    
  358.     ENV1_VCF_CUTOFF=0;
  359.     ENV1_VCF_RESONANCE=0;    
  360.  
  361.     ENV2_OSC1_PW=0;
  362.     ENV2_OSC2_PW=0;
  363.     ENV2_OSC1_PITCH=0;
  364.     ENV2_OSC2_PITCH=0;
  365.     ENV2_OSC1_VOLUME=0;
  366.     ENV2_OSC2_VOLUME=0;    
  367.     ENV2_VCF_CUTOFF=0;
  368.     ENV2_VCF_RESONANCE=0;    
  369.     
  370.     OSC1_freakpw1=0;
  371.     OSC1_freakpw2=0;
  372.     OSC2_freakpw1=0;
  373.     OSC2_freakpw2=0;
  374.  
  375.     OSC1_POSITION=0;
  376.     OSC2_POSITION=0;
  377.     OSC3_POSITION=0;
  378.     TOSC1_POSITION=0;
  379.     TOSC2_POSITION=0;
  380.     
  381.     OSC3_SWITCH=false;
  382.  
  383.     OSC1_STEP=0;
  384.     OSC2_STEP=0;
  385.     OSC3_STEP=0;
  386.     
  387.     T_OSC1_STEP=0;
  388.     T_OSC2_STEP=0;
  389.     VT_OSC1_STEP=0;
  390.     VT_OSC2_STEP=0;
  391.     
  392.     ENV1_STAGE=0;
  393.     ENV2_STAGE=0;
  394.  
  395.     ENV1_COUNTER=0;
  396.     ENV2_COUNTER=0;
  397.  
  398.     ENV1_VALUE=0;
  399.     ENV2_VALUE=0;
  400.     
  401.     GS_VAL=0;
  402.     
  403.     OSC3_VOLUME=0;
  404.  
  405.     PTC_GLIDE=1.0f;
  406.  
  407.     /* Initializing SINETABLE */
  408.  
  409.     for (int ini=0;ini<360;ini++)
  410.         SIN[ini]=(float)sin(ini*0.0174532);
  411.  
  412. }
  413.  
  414. /* This next function returns (gives) a 32-bit float value (sample),
  415. where:
  416.  
  417.   This function is for internal use only.
  418.  
  419. - Type is the wavetype [0-Sine, 1-Sawtooth, 2-Pulse, 3-Random, 4-Thru (off)]
  420. - offset is a float oscillator offset. Range: [0.0,512.0)
  421. - pwi is a float pulsewidth amount. Range: [0.0,512.0]
  422. */
  423.  
  424. float CSynth::SynthGetOscValue(char type,float offset)
  425. {
  426.     switch(type)
  427.     {
  428.  
  429.         /* Sine */    
  430.  
  431.         case 0: 
  432.             return (float)sin(offset*0.0122718)*16384;
  433.         break;
  434.         
  435.         /* SawTooth */
  436.  
  437.         case 1: 
  438.             return offset*64;
  439.         break;
  440.         
  441.         /* Pulse */
  442.  
  443.         case 2:
  444.             if (offset<0)
  445.             return 16384;
  446.             else
  447.             return -16384;
  448.         break;
  449.         
  450.         /* Noise */
  451.  
  452.         case 3:
  453.             return (float)rand()-16384;
  454.         break;
  455.         
  456.         /* Silence */
  457.  
  458.         case 4: 
  459.             return 0;
  460.         break;
  461.         
  462.         /* Default Nothing */
  463.         
  464.         default:
  465.             return 0;
  466.         break;
  467.     }
  468. }
  469.  
  470. /* This next function is for internal use only. Makes the LFO's run. */
  471.  
  472. void CSynth::SynthLfoAdvance(void)
  473. {
  474.         LFO1_SUBGRCOUNTER++;
  475.         LFO2_SUBGRCOUNTER++;
  476.         
  477.         if(LFO1_SUBGRCOUNTER>LFO1_SUBGRMAX)
  478.         {
  479.             LFO1_SUBGRCOUNTER=0;
  480.             LFO1_GR++;
  481.  
  482.             if(LFO1_GR>359)
  483.             LFO1_GR=0;
  484.  
  485.             LFO1_VALUE=SIN[LFO1_GR];
  486.  
  487.         }
  488.  
  489.         if(LFO2_SUBGRCOUNTER>LFO2_SUBGRMAX)
  490.         {
  491.             LFO2_SUBGRCOUNTER=0;
  492.             LFO2_GR++;
  493.             if(LFO2_GR>359)
  494.                 LFO2_GR=0;
  495.             LFO2_VALUE=SIN[LFO2_GR];
  496.  
  497.         }
  498.  
  499. }
  500.  
  501. /* The cooler NoteOn typical message for this Class CSynth Objects =]. */
  502.  
  503. void CSynth::SynthNoteOn(float note, float speed)
  504. {
  505.     
  506.     /* Triggering ENV1 and ENV2, most synths trigger ENVs when 
  507.     a note on message is received... but, well, change that if
  508.     you want. */
  509.  
  510.     ENV1_STAGE=1; /* '0' is off, '1' starts the attack */
  511.     ENV2_STAGE=1;
  512.     
  513.     ENV1_COUNTER=0; /* Envelope stage counter, in samples */
  514.     ENV2_COUNTER=0;
  515.  
  516.     /* Attack ENVELOPES from current level 8)....
  517.     Most coders reset env-value to 0 and compute, and this is
  518.     a terrible error, since we have to compute a relative ramp
  519.     from the current level to 1.0, since not always we receive noteon
  520.     when the last note is released or the volume is 0.
  521.     This will avoid 'clicking' and make the synth smoother. */
  522.  
  523.     /* The same process is made on Note Off message too */
  524.     
  525.     /* Compute correct attack coefficients here */
  526.  
  527.     ENV1_A_COEF=(1.0f-ENV1_VALUE)/ENV1_ATTACK;
  528.     ENV2_A_COEF=(1.0f-ENV2_VALUE)/ENV2_ATTACK;
  529.  
  530.     /* Assign resampling steps to each oscillator: */
  531.  
  532.     OSC1_STEP=(float)pow(2.0,note/12.0f);
  533.     OSC2_STEP=(float)pow(2.0,(note+OSC2_FINETUNE+OSC2_DETUNE)/12.0f);
  534.     OSC3_STEP=OSC1_STEP*0.5f;
  535.     
  536.     OSC1_freakpw1=OSC1_STEP*2;
  537.     OSC1_freakpw2=512-OSC1_STEP*2;
  538.  
  539.     OSC2_freakpw1=OSC2_STEP*2;
  540.     OSC2_freakpw2=512-OSC2_STEP*2;
  541.     GLOBAL_VOLUME=speed;
  542. }
  543.  
  544. /* Envelope run function */
  545.  
  546. void CSynth::SynthEnvRun(void)
  547. {
  548.     /* ENV1 */
  549.  
  550.     switch(ENV1_STAGE)
  551.     {
  552.  
  553.     /* Attack */
  554.  
  555.     case 1:
  556.     ENV1_VALUE+=ENV1_A_COEF;
  557.     ENV1_COUNTER++;
  558.  
  559.     if (ENV1_COUNTER==ENV1_ATTACK)
  560.     {
  561.         ENV1_COUNTER=0;
  562.         ENV1_STAGE=2;
  563.     }
  564.     break;
  565.  
  566.     /* Decay */
  567.  
  568.     case 2:
  569.     ENV1_VALUE-=ENV1_D_COEF;
  570.     ENV1_COUNTER++;
  571.  
  572.     if (ENV1_COUNTER==ENV1_DECAY)
  573.     {
  574.         ENV1_COUNTER=0;
  575.         ENV1_STAGE=3;
  576.     }
  577.     break;
  578.  
  579.     /* Sustain */
  580.  
  581.     case 3:
  582.     ENV1_VALUE=ENV1_SUSTAIN;
  583.     break;
  584.  
  585.     /* Release */
  586.  
  587.     case 4:
  588.     ENV1_VALUE-=ENV1_R_COEF;
  589.     ENV1_COUNTER++;
  590.  
  591.     if (ENV1_COUNTER==ENV1_RELEASE)
  592.     {
  593.         ENV1_COUNTER=0;
  594.         ENV1_STAGE=0; /* Stop the rock ENV1 */
  595.     }
  596.     break;
  597.         
  598.     } // Envelope 1 runned
  599.  
  600.     /* ENV2 */
  601.  
  602.     switch(ENV2_STAGE)
  603.     {
  604.  
  605.     /* Attack */
  606.  
  607.     case 1:
  608.     ENV2_VALUE+=ENV2_A_COEF;
  609.     ENV2_COUNTER++;
  610.  
  611.     if (ENV2_COUNTER==ENV2_ATTACK)
  612.     {
  613.         ENV2_COUNTER=0;
  614.         ENV2_STAGE=2;
  615.     }
  616.     break;
  617.  
  618.     /* Decay */
  619.  
  620.     case 2:
  621.     ENV2_VALUE-=ENV2_D_COEF;
  622.     ENV2_COUNTER++;
  623.  
  624.     if (ENV2_COUNTER==ENV2_DECAY)
  625.     {
  626.         ENV2_COUNTER=0;
  627.         ENV2_STAGE=3;
  628.     }
  629.     break;
  630.  
  631.     /* Sustain */
  632.  
  633.     case 3:
  634.     ENV2_VALUE=ENV2_SUSTAIN;
  635.     break;
  636.  
  637.     /* Release */
  638.  
  639.     case 4:
  640.     ENV2_VALUE-=ENV2_R_COEF;
  641.     ENV2_COUNTER++;
  642.  
  643.     if (ENV2_COUNTER==ENV2_RELEASE)
  644.     {
  645.         ENV2_COUNTER=0;
  646.         ENV2_STAGE=0; /* Stop the rock ENV2 */
  647.     }
  648.     break;
  649.         
  650.     } // Envelope 2 runned
  651. }
  652.  
  653. /* 'Note Off' message for CSynth class objects */
  654.  
  655. void CSynth::SynthNoteOff(void)
  656. {
  657.     if (ENV1_STAGE>0 && ENV1_STAGE<4)
  658.     {
  659.         ENV1_R_COEF=ENV1_VALUE/(float)ENV1_RELEASE;
  660.         ENV1_COUNTER=0;
  661.         ENV1_STAGE=4;
  662.     }
  663.  
  664.     if (ENV2_STAGE>0 && ENV2_STAGE<4)
  665.     {
  666.         ENV2_R_COEF=ENV2_VALUE/(float)ENV2_RELEASE;
  667.         ENV2_COUNTER=0;
  668.         ENV2_STAGE=4;
  669.     }
  670. }
  671.  
  672. /* This function must be called every time that you change any
  673.    envelope (ENV1 or ENV2) value: ATTACK, DECAY, SUSTAIN or RELEASE.
  674.  
  675.    Technically: it compute 'increase-coef' for each envelope stage.
  676. */
  677.  
  678. void CSynth::SynthEnvUpdate(void)
  679. {
  680.     /* Update ENV1 */
  681.  
  682.     ENV1_A_COEF=1.0f/(float)ENV1_ATTACK;
  683.     ENV1_D_COEF=(1.0f-ENV1_SUSTAIN)/(float)ENV1_DECAY;
  684.     ENV1_R_COEF=ENV1_SUSTAIN/(float)ENV1_RELEASE;
  685.  
  686.     /* Update ENV2 */
  687.  
  688.     ENV2_A_COEF=1.0f/(float)ENV2_ATTACK;
  689.     ENV2_D_COEF=(1.0f-ENV2_SUSTAIN)/(float)ENV2_DECAY;
  690.     ENV2_R_COEF=ENV2_SUSTAIN/(float)ENV2_RELEASE;
  691. }
  692.  
  693. /* The cool/render function, gets the next synth sample. */
  694.  
  695. float CSynth::SynthGetSample(void)
  696. {
  697.  
  698. GS_VAL=0;
  699.  
  700. /* Oscillator1 On */
  701.  
  702. if(OSC1_WAVEFORM!=4) 
  703. {
  704.  
  705. T_OSC1_VOLUME=
  706. LFO1_VALUE*LFO1_OSC1_VOLUME
  707. +LFO2_VALUE*LFO2_OSC1_VOLUME
  708. +ENV1_VALUE*ENV1_OSC1_VOLUME
  709. +ENV2_VALUE*ENV2_OSC1_VOLUME
  710. ;
  711.  
  712. T_OSC1_PW=OSC1_PW
  713. +LFO1_VALUE*LFO1_OSC1_PW*256
  714. +LFO2_VALUE*LFO2_OSC1_PW*256
  715. +ENV1_VALUE*ENV1_OSC1_PW*256
  716. +ENV2_VALUE*ENV2_OSC1_PW*256;
  717.  
  718. GS_VAL+=SynthGetOscValue(OSC1_WAVEFORM,TOSC1_POSITION)*T_OSC1_VOLUME;
  719.  
  720. T_OSC1_STEP=OSC1_STEP
  721. +LFO1_VALUE*LFO1_OSC1_PITCH
  722. +LFO2_VALUE*LFO2_OSC1_PITCH
  723. +ENV1_VALUE*ENV1_OSC1_PITCH
  724. +ENV2_VALUE*ENV2_OSC1_PITCH;
  725.  
  726. if (T_OSC1_STEP<0.0f)T_OSC1_STEP=0.0f;
  727.  
  728. // Glide Work --------------------------------------------------------
  729.  
  730. if(VT_OSC1_STEP<T_OSC1_STEP)
  731. {
  732.     VT_OSC1_STEP+=PTC_GLIDE;
  733.     if(VT_OSC1_STEP>T_OSC1_STEP)VT_OSC1_STEP=T_OSC1_STEP;
  734. }
  735.  
  736. if(VT_OSC1_STEP>T_OSC1_STEP)
  737. {
  738.     VT_OSC1_STEP-=PTC_GLIDE;
  739.     if(VT_OSC1_STEP<T_OSC1_STEP)VT_OSC1_STEP=T_OSC1_STEP;
  740. }
  741.  
  742.  
  743. // Phase distortion OSC1
  744.  
  745. float pw=T_OSC1_PW+256;
  746. if(pw<OSC1_freakpw1)pw=OSC1_freakpw1;
  747. if(pw>OSC1_freakpw2)pw=OSC1_freakpw2;
  748. float lcoef=256/pw;
  749. float rcoef=256/(512-pw);
  750.  
  751. if(OSC1_POSITION<T_OSC1_PW)
  752. TOSC1_POSITION+=VT_OSC1_STEP*lcoef;
  753. else
  754. TOSC1_POSITION+=VT_OSC1_STEP*rcoef;
  755.  
  756. OSC1_POSITION+=VT_OSC1_STEP;
  757. if (OSC1_POSITION>=256){OSC1_POSITION-=512;TOSC1_POSITION=-256;}
  758.  
  759. }
  760.  
  761. /* Oscillator2 On */
  762.  
  763. if(OSC2_WAVEFORM!=4) 
  764. {
  765.  
  766. T_OSC2_VOLUME=
  767. LFO1_VALUE*LFO1_OSC2_VOLUME
  768. +LFO2_VALUE*LFO2_OSC2_VOLUME
  769. +ENV1_VALUE*ENV1_OSC2_VOLUME
  770. +ENV2_VALUE*ENV2_OSC2_VOLUME;
  771.  
  772. T_OSC2_PW=OSC2_PW
  773. +LFO1_VALUE*LFO1_OSC2_PW*256
  774. +LFO2_VALUE*LFO2_OSC2_PW*256
  775. +ENV1_VALUE*ENV1_OSC2_PW*256
  776. +ENV2_VALUE*ENV2_OSC2_PW*256;
  777.  
  778. GS_VAL+=SynthGetOscValue(OSC2_WAVEFORM,TOSC2_POSITION)*T_OSC2_VOLUME;
  779.  
  780. T_OSC2_STEP=OSC2_STEP
  781. +LFO1_VALUE*LFO1_OSC2_PITCH
  782. +LFO2_VALUE*LFO2_OSC2_PITCH
  783. +ENV1_VALUE*ENV1_OSC2_PITCH
  784. +ENV2_VALUE*ENV2_OSC2_PITCH;
  785.  
  786. if (T_OSC2_STEP<0.0f)T_OSC2_STEP=0.0f;
  787.  
  788. // Glide Work --------------------------------------------------------
  789.  
  790. if(VT_OSC2_STEP<T_OSC2_STEP)
  791. {
  792.     VT_OSC2_STEP+=PTC_GLIDE;
  793.     if(VT_OSC2_STEP>T_OSC2_STEP)VT_OSC2_STEP=T_OSC2_STEP;
  794. }
  795.  
  796. if(VT_OSC2_STEP>T_OSC2_STEP)
  797. {
  798.     VT_OSC2_STEP-=PTC_GLIDE;
  799.     if(VT_OSC2_STEP<T_OSC2_STEP)VT_OSC2_STEP=T_OSC2_STEP;
  800. }
  801.  
  802. // Phase distortion OSC2
  803.  
  804. float pw=T_OSC2_PW+256;
  805. if(pw<OSC2_freakpw1)pw=OSC2_freakpw1;
  806. if(pw>OSC2_freakpw2)pw=OSC2_freakpw2;
  807. float lcoef=256/pw;
  808. float rcoef=256/(512-pw);
  809.  
  810. if(OSC2_POSITION<T_OSC2_PW)
  811. TOSC2_POSITION+=VT_OSC2_STEP*lcoef;
  812. else
  813. TOSC2_POSITION+=VT_OSC2_STEP*rcoef;
  814.  
  815. OSC2_POSITION+=VT_OSC2_STEP;
  816. if (OSC2_POSITION>=256){OSC2_POSITION-=512;TOSC2_POSITION=-256;}
  817.  
  818. }
  819.  
  820. if(OSC3_SWITCH) /* SubOscillator On */
  821. {
  822. GS_VAL+=SynthGetOscValue(OSC1_WAVEFORM,OSC3_POSITION)*T_OSC1_VOLUME*OSC3_VOLUME;
  823. OSC3_POSITION+=OSC3_STEP;
  824. if (OSC3_POSITION>=256)OSC3_POSITION-=512;
  825. }
  826.  
  827. GS_VAL=SynthFilter(GS_VAL)*GLB_VOLUME;
  828.  
  829. /* Advance all, oscillator, envelopes, and lfo's */
  830.  
  831. SynthEnvRun();
  832. SynthLfoAdvance();
  833.  
  834. /* Return value */
  835. return GS_VAL*GLOBAL_VOLUME;
  836. }
  837.  
  838. void CSynth::SynthChangeParameters(SynthParameters TSP)
  839. {
  840. /* Function body */
  841.  
  842. OSC1_WAVEFORM=TSP.osc1_waveform;
  843. OSC2_WAVEFORM=TSP.osc2_waveform;
  844.  
  845. OSC1_PW=(float)TSP.osc1_pw-256;
  846. OSC2_PW=(float)TSP.osc2_pw-256;
  847.  
  848. OSC2_DETUNE=(float)TSP.osc2_detune-64.0f;
  849. OSC2_FINETUNE=(float)TSP.osc2_finetune*0.0078125f;    
  850.  
  851. VCF_CUTOFF=(float)TSP.vcf_cutoff*0.0078125f;
  852. VCF_RESONANCE=(float)TSP.vcf_resonance*0.0078125f;
  853. VCF_TYPE=TSP.vcf_type;
  854.  
  855. ENV1_ATTACK=TSP.env1_attack+1;
  856. ENV1_DECAY=TSP.env1_decay+1;
  857. ENV1_SUSTAIN=(float)TSP.env1_sustain*0.0078125f;
  858. ENV1_RELEASE=TSP.env1_release+1;
  859.  
  860. ENV2_ATTACK=TSP.env2_attack+1;
  861. ENV2_DECAY=TSP.env2_decay+1;
  862. ENV2_SUSTAIN=(float)TSP.env2_sustain*0.0078125f;
  863. ENV2_RELEASE=TSP.env2_release+1;
  864.     
  865. LFO1_PERIOD=(float)TSP.lfo1_period+1;
  866. LFO1_SUBGRMAX=f2i(((float)SamplesPerTick*0.000277f)*LFO1_PERIOD);
  867.  
  868. LFO2_PERIOD=(float)TSP.lfo2_period+1;
  869. LFO2_SUBGRMAX=f2i(((float)SamplesPerTick*0.000277f)*LFO2_PERIOD);
  870.  
  871. /* Envelopes and LFO's matrix modulation variables */
  872.  
  873. LFO1_OSC1_PW=      ((float)TSP.lfo1_osc1_pw-64)*0.015625f;
  874. LFO1_OSC2_PW=      ((float)TSP.lfo1_osc2_pw-64)*0.015625f;
  875. LFO1_OSC1_PITCH=   ((float)TSP.lfo1_osc1_pitch-64)*0.015625f;
  876. LFO1_OSC2_PITCH=   ((float)TSP.lfo1_osc2_pitch-64)*0.015625f;
  877. LFO1_OSC1_VOLUME=  ((float)TSP.lfo1_osc1_volume-64)*0.015625f;
  878. LFO1_OSC2_VOLUME=  ((float)TSP.lfo1_osc2_volume-64)*0.015625f;
  879. LFO1_VCF_CUTOFF=   ((float)TSP.lfo1_vcf_cutoff-64)*0.015625f;
  880. LFO1_VCF_RESONANCE=((float)TSP.lfo1_vcf_resonance-64)*0.015625f;
  881.  
  882. LFO2_OSC1_PW=      ((float)TSP.lfo2_osc1_pw-64)*0.015625f;
  883. LFO2_OSC2_PW=      ((float)TSP.lfo2_osc2_pw-64)*0.015625f;
  884. LFO2_OSC1_PITCH=   ((float)TSP.lfo2_osc1_pitch-64)*0.015625f;
  885. LFO2_OSC2_PITCH=   ((float)TSP.lfo2_osc2_pitch-64)*0.015625f;
  886. LFO2_OSC1_VOLUME=  ((float)TSP.lfo2_osc1_volume-64)*0.015625f;
  887. LFO2_OSC2_VOLUME=  ((float)TSP.lfo2_osc2_volume-64)*0.015625f;
  888. LFO2_VCF_CUTOFF=   ((float)TSP.lfo2_vcf_cutoff-64)*0.015625f;
  889. LFO2_VCF_RESONANCE=((float)TSP.lfo2_vcf_resonance-64)*0.015625f;
  890.  
  891. ENV1_OSC1_PW=      ((float)TSP.env1_osc1_pw-64)*0.015625f;
  892. ENV1_OSC2_PW=      ((float)TSP.env1_osc2_pw-64)*0.015625f;
  893. ENV1_OSC1_PITCH=   ((float)TSP.env1_osc1_pitch-64)*0.015625f;
  894. ENV1_OSC2_PITCH=   ((float)TSP.env1_osc2_pitch-64)*0.015625f;
  895. ENV1_OSC1_VOLUME=  ((float)TSP.env1_osc1_volume-64)*0.015625f;
  896. ENV1_OSC2_VOLUME=  ((float)TSP.env1_osc2_volume-64)*0.015625f;
  897. ENV1_VCF_CUTOFF=   ((float)TSP.env1_vcf_cutoff-64)*0.015625f;
  898. ENV1_VCF_RESONANCE=((float)TSP.env1_vcf_resonance-64)*0.015625f;
  899.  
  900. ENV2_OSC1_PW=      ((float)TSP.env2_osc1_pw-64)*0.015625f;
  901. ENV2_OSC2_PW=      ((float)TSP.env2_osc2_pw-64)*0.015625f;
  902. ENV2_OSC1_PITCH=   ((float)TSP.env2_osc1_pitch-64)*0.015625f;
  903. ENV2_OSC2_PITCH=   ((float)TSP.env2_osc2_pitch-64)*0.015625f;
  904. ENV2_OSC1_VOLUME=  ((float)TSP.env2_osc1_volume-64)*0.015625f;
  905. ENV2_OSC2_VOLUME=  ((float)TSP.env2_osc2_volume-64)*0.015625f;
  906. ENV2_VCF_CUTOFF=   ((float)TSP.env2_vcf_cutoff-64)*0.015625f;
  907. ENV2_VCF_RESONANCE=((float)TSP.env2_vcf_resonance-64)*0.015625f;
  908. OSC3_VOLUME=       ((float)TSP.osc3_volume-64)*0.015625f;
  909. PTC_GLIDE=           ((float)TSP.ptc_glide*(float)TSP.ptc_glide)*0.0000015625f;
  910. OSC3_SWITCH=TSP.osc3_switch;
  911. GLB_VOLUME=           ((float)TSP.glb_volume)*0.0078125f;
  912.  
  913. SynthEnvUpdate(); /* Update envelopes coefficients */
  914. }
  915.  
  916. /* Next Function: used to reset synthparameters Structure */
  917. /* Well, I think the default preset is not very cool, but nah! */
  918.  
  919. void ResetSynthParameters(SynthParameters *TSP)
  920. {
  921. sprintf(TSP->presetname,"Untitled");
  922. TSP->osc1_waveform=1;
  923. TSP->osc2_waveform=1;
  924. TSP->osc1_pw=256;
  925. TSP->osc2_pw=256;
  926. TSP->osc2_detune=64;
  927. TSP->osc2_finetune=16;
  928. TSP->vcf_cutoff=64;
  929. TSP->vcf_resonance=64;
  930. TSP->vcf_type=0;
  931. TSP->env1_attack=2560;
  932. TSP->env1_decay=2560;
  933. TSP->env1_sustain=16;
  934. TSP->env1_release=16384;
  935. TSP->env2_attack=2560;
  936. TSP->env2_decay=2560;
  937. TSP->env2_sustain=16;
  938. TSP->env2_release=16384;
  939. TSP->lfo1_period=16;
  940. TSP->lfo2_period=16;
  941. TSP->lfo1_osc1_pw=64;
  942. TSP->lfo1_osc2_pw=64;
  943. TSP->lfo1_osc1_pitch=64;
  944. TSP->lfo1_osc2_pitch=64;
  945. TSP->lfo1_osc1_volume=64;
  946. TSP->lfo1_osc2_volume=64;    
  947. TSP->lfo1_vcf_cutoff=64;
  948. TSP->lfo1_vcf_resonance=64;    
  949. TSP->lfo2_osc1_pw=64;
  950. TSP->lfo2_osc2_pw=64;
  951. TSP->lfo2_osc1_pitch=64;
  952. TSP->lfo2_osc2_pitch=64;
  953. TSP->lfo2_osc1_volume=64;
  954. TSP->lfo2_osc2_volume=64;    
  955. TSP->lfo2_vcf_cutoff=64;
  956. TSP->lfo2_vcf_resonance=64;    
  957. TSP->env1_osc1_pw=64;
  958. TSP->env1_osc2_pw=64;
  959. TSP->env1_osc1_pitch=64;
  960. TSP->env1_osc2_pitch=64;
  961. TSP->env1_osc1_volume=128;
  962. TSP->env1_osc2_volume=128;    
  963. TSP->env1_vcf_cutoff=64;
  964. TSP->env1_vcf_resonance=64;    
  965. TSP->env2_osc1_pw=64;
  966. TSP->env2_osc2_pw=64;
  967. TSP->env2_osc1_pitch=64;
  968. TSP->env2_osc2_pitch=64;
  969. TSP->env2_osc1_volume=64;
  970. TSP->env2_osc2_volume=64;
  971. TSP->env2_vcf_cutoff=64;
  972. TSP->env2_vcf_resonance=64;    
  973. TSP->osc3_volume=128;
  974. TSP->ptc_glide=64;
  975. TSP->osc3_switch=false;
  976. TSP->glb_volume=128;
  977.  
  978. }
  979.  
  980. float CSynth::SynthFilter(float input)
  981. {
  982.   if (VCF_TYPE<2)
  983.   {
  984.     input++;
  985.       float f=VCF_CUTOFF
  986.     +LFO1_VALUE*LFO1_VCF_CUTOFF
  987.     +LFO2_VALUE*LFO2_VCF_CUTOFF
  988.     +ENV1_VALUE*ENV1_VCF_CUTOFF
  989.     +ENV2_VALUE*ENV2_VCF_CUTOFF;
  990.   
  991.     float q=VCF_RESONANCE
  992.     +LFO1_VALUE*LFO1_VCF_RESONANCE
  993.     +LFO2_VALUE*LFO2_VCF_RESONANCE
  994.     +ENV1_VALUE*ENV1_VCF_RESONANCE
  995.     +ENV2_VALUE*ENV2_VCF_RESONANCE;
  996.     
  997.     if (f<0.05f)f=0.05f;
  998.     if (f>0.90f)f=0.90f;
  999.     if (q<0.05f)q=0.05f;
  1000.     if (q>0.98f)q=0.98f;
  1001.  
  1002.   float fa = float(1.0 - f); 
  1003.   float fb = float(q * (1.0 + (1.0/fa)));
  1004.   sbuf0 = fa * sbuf0 + f * (input + fb * (sbuf0 - sbuf1)); 
  1005.   sbuf1 = fa * sbuf1 + f * sbuf0;
  1006.   
  1007.   return (VCF_TYPE==0?sbuf1:input-sbuf1);  
  1008.   }
  1009.   else 
  1010.   return input;
  1011. }
  1012.  
  1013. class rFilter{
  1014. private: 
  1015.     float buffy0;
  1016.     float buffy1;
  1017.  
  1018. public:
  1019.  
  1020.     rFilter()
  1021.     {
  1022.             buffy0=0;
  1023.             buffy0=1;
  1024.     };
  1025.  
  1026.     float fWork(float input,float f)
  1027.     {
  1028.     float fa = float(1.0 - f); 
  1029.     buffy0 = fa * buffy0 + f * input; 
  1030.     buffy1 = fa * buffy1 + f * buffy0;
  1031.     return buffy1;  
  1032. };
  1033.  
  1034. };
  1035.